package com.event.management.frontend.config;

import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.filter.SaServletFilter;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import com.event.management.frontend.common.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * Sa-Token配置类
 */
@Configuration
public class SaTokenConfig implements WebMvcConfigurer {

    /**
     * 注册Sa-Token的注解拦截器，打开注解式鉴权功能
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册注解拦截器，并排除不需要注解鉴权的接口地址
        registry.addInterceptor(new SaInterceptor())
                .addPathPatterns("/**");
    }
    
    /**
     * 注册Sa-Token过滤器
     * @return SaServletFilter
     */
    @Bean
    public SaServletFilter saServletFilter() {
        return new SaServletFilter()
                // 拦截路径
                .addInclude("/**")
                .setAuth(obj -> {
                    // 不设置全局拦截，完全依靠注解进行登录校验
                    // 具体接口上添加 @SaCheckLogin 注解才会检查登录状态
                })
                // 异常处理
                .setError(e -> {
                    Result<?> result = Result.fail(401, "请先登录后再操作");
                    try {
                        return new ObjectMapper().writeValueAsString(result);
                    } catch (Exception ex) {
                        return "{\"code\": 401, \"msg\": \"请先登录后再操作\", \"data\": null}";
                    }
                })
                // 前置处理：跨域配置等
                .setBeforeAuth(obj -> {
                    // 设置跨域相关响应头
                    SaHolder.getResponse()
                        .setHeader("Access-Control-Allow-Origin", "*")
                        .setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
                        .setHeader("Access-Control-Max-Age", "3600")
                        .setHeader("Access-Control-Allow-Headers", "token, Authorization, Content-Type, satoken, frontToken");
                    
                    // 对于OPTIONS请求直接放行
                    if(SaHolder.getRequest().getMethod().equals("OPTIONS")) {
                        SaRouter.back();
                    }
                });
    }
} 